package cn.tedu.ivos.audit.service.impl;

import cn.tedu.ivos.application.mapper.ApplicationMapper;
import cn.tedu.ivos.application.pojo.entity.Application;
import cn.tedu.ivos.audit.mapper.AuditMapper;
import cn.tedu.ivos.audit.pojo.dto.AuditQuery;
import cn.tedu.ivos.audit.pojo.dto.AuditSaveParam;
import cn.tedu.ivos.audit.pojo.entity.Audit;
import cn.tedu.ivos.audit.pojo.vo.AuditVO;
import cn.tedu.ivos.audit.service.AuditService;
import cn.tedu.ivos.base.enums.ApplicationStatusEnum;
import cn.tedu.ivos.base.enums.AuditStatusEnum;
import cn.tedu.ivos.user.mapper.UserMapper;
import cn.tedu.ivos.user.pojo.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.*;

@Service
@Transactional
@Slf4j
public class AuditServiceImpl implements AuditService {
    @Autowired
    AuditMapper auditMapper;

    @Autowired
    UserMapper userMapper;
    @Autowired
    ApplicationMapper applicationMapper;

    @Override
    public void insertAudit(Application application) {
        log.debug("为申请单生成对应的审批单业务：application={}",application);
//        1。获取审批人id集合【106 103】
        List<Long> userIdList = application.getAuditUserIdList();
//        2、遍历审批人集合 有几个审批人就生成几条审批数据
        for (int i = 0; i < userIdList.size(); i++) {
            //3.设置当期审批单的相关数据
            Audit audit = new Audit();
            audit.setApplicationId(application.getId());//设置申请单id
            audit.setAuditUserId(userIdList.get(i));//设置审批人id
            //设置审批次序， 直属领导次序为0 上上级次序为1
            audit.setAuditSort(i);
            //4、设置每条审批单的状态：
            if (i == 0) {
                //0 表示为第一条审批数据，直属领导的审批单状态为“待我审核”
                audit.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
            } else {
                //1 表示为第2条审批数据，上上级领导的审批单状态为“待他人审核”
                audit.setAuditStatus(AuditStatusEnum.PENDING.getCode());
            }
            //5、 设置创建时间：
            audit.setCreateTime(new Date());
            //6、每循环一次，向数据库插入一条审批数据：
            auditMapper.insert(audit);
        }
    }

    @Override
    public List<AuditVO> selectAuditByApplicationId(Long id) {
        return auditMapper.selectAuditByApplicationId(id);
    }
    @Override
    public List<AuditVO> selectAudit(AuditQuery auditQuery) {
        log.debug("查询审批单数据：auditQuery={}",auditQuery);
        List<AuditVO> auditVOList = auditMapper.selectAudit(auditQuery);

        for (int i=0;i<auditVOList.size();i++){
            AuditVO auditVO = auditVOList.get(i);
            assignAuditUserList(auditVO);
        }
        return auditVOList;
    }

    private void assignAuditUserList(AuditVO auditVO) {
        //1.创建一个用来装审批人姓名的空集合
        List<String> auditUsernameList = new ArrayList<>();
        //创建一个用来装审批人id的空集合
        List<Long> auditUserIdList =new ArrayList<>();
        //3、根据审批单VO中的申请单id，查询当期审批单对应的申请单下的所有审批单数据
        List<AuditVO> auditVOList =auditMapper.selectAuditByApplicationId(auditVO.getApplicationId());
        //遍历每一个审批单 获取每个审批单中的审批人id与姓名
        for (int i =0; i<auditVOList.size();i++){
            //获取当前遍历到的审批单的审批人id
            Long userId = auditVOList.get(i).getAuditUserId();
            //将当前的审批人id装到上面的id空集合中
            auditUserIdList.add(userId);
            //根据用户id查出用户VO
            UserVO user = userMapper.selectById(userId);
            //将当前的审批人姓名装到上面的name空集合中
            auditUsernameList.add(user.getUsername());
        }
        //准备拼接工具
        StringJoiner stringJoiner = new StringJoiner(",");
        for (String username : auditUsernameList){//遍历审批人姓名集合并进行拼接
            stringJoiner.add(username);
        }
        //将审批人姓名字符串赋值给审批单VO
        auditVO.setAuditUserIdList(auditUserIdList);
        //将审批人的id数据赋值给审批单vo
        auditVO.setAuditUsernameList(stringJoiner.toString());
//        //1.创建一个空集合：
//        List<String> auditUsernameList = new ArrayList<>();
//        List<Long> auditUserIdList =new ArrayList<>();
//        //2、根据审批单中的vo的id去查询审批单数据
//        List<AuditVO> auditVOList = auditMapper.selectAuditByApplicationId(auditVO.getAuditUserId());
//        for (int i = 0;i<auditVOList.size();i++){
//            Long userId = auditVOList.get(i).getAuditUserId();
//            auditUserIdList.add(userId);
//
//            UserVO user = userMapper.selectById(userId);
//            auditUsernameList.add(user.getUsername());
//        }
//        //拼接：
//        StringJoiner stringJoiner = new StringJoiner(",");
//        for (String username : auditUsernameList){
//            stringJoiner.add(username);
//        }
//        auditVO.setAuditUsernameList(stringJoiner.toString());
//        auditVO.setAuditUserIdList(auditUserIdList);
    }


    @Override
    public void updateAudit(AuditSaveParam auditSaveParam) {
        log.debug("更新审批单（通过、驳回）：auditSaveParam={}",auditSaveParam);
        Audit audit = new Audit();
        BeanUtils.copyProperties(auditSaveParam,audit);
        audit.setUpdateTime(new Date());
        //找到当前审批对应的申请单对象：
        Application application = new Application();
        application.setId(audit.getApplicationId());
        application.setUpdateTime(new Date());
        //判断前端传过来的审批单状态是 通过 还是 驳回 分别针对不同的审批操作做后续的处理
        if (audit.getAuditStatus().equals(AuditStatusEnum.AUDITED.getCode())){//审批通过
            //更新当前审批单：
            auditMapper.update(audit);
            //我们要继续查其他的审批单 与当前审批单审核同一个申请单的审批单（不知到当前的审批单有几个人审批）：
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            //根据申请单id查询当前申请单对应的所有的为审批的审批单总数（注意；当前审批单已审批通过）
            Integer count =  auditMapper.selectRestAuditCount(auditQuery);
            if (count>0){//有未审批的审批单
                //下一条审批单是当前审批单的次序+1
                auditQuery.setAuditSort(audit.getAuditSort()+1);
                //根据申请单id与审批次序查出来下一条审批单
                List<AuditVO> auditVOList = auditMapper.selectAudit(auditQuery);
                if (auditVOList !=null && auditVOList.size()>0){
                    AuditVO auditVO = auditVOList.get(0);
                    //创建第二个空的审批对象，准备更新数据库：
                    Audit audit2 = new Audit();
                    audit2.setId(auditVO.getId());
                    //设置第2条审批单的状态为待我审核：
                    audit2.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
                    auditMapper.update(audit2);
                }
                //设置申请单状态为审核中：
                application.setStatus(ApplicationStatusEnum.AUDIT.getCode());
                applicationMapper.update(application);
            }else {//没有未审批的审批单
                //申请单已审核 修改申请单状态为：审核通过(后续可以分配车辆)
                application.setStatus(ApplicationStatusEnum.AUDITED.getCode());
                applicationMapper.update(application);
            }

        }else if (audit.getAuditStatus().equals(AuditStatusEnum.REJECT.getCode())){//审批驳回
            auditMapper.update(audit);//更新当前审批单 驳回状态 驳回原因 更新时间
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            //根据申请单id 查到审批此申请单的所有审批单VO对象
            List<AuditVO> auditVOList = auditMapper.selectAudit(auditQuery);
            //判断是否能查到审批单对象：
            if (auditVOList !=null && auditVOList.size()>0){
                for (int i = 0; i <auditVOList.size(); i++){
                    AuditVO auditVO = auditVOList.get(i);
                    if (AuditStatusEnum.PENDING.getCode().equals(auditVO.getAuditStatus())){
                        auditMapper.deleteById(auditVO.getId());
                    }
                }
            }
            //设置申请单的状态为 已驳回 并设置驳回原因：
            application.setStatus(ApplicationStatusEnum.REJECT.getCode());
            application.setRejectReason(auditSaveParam.getRejectReason());
            applicationMapper.update(application);
        }
    }

}
